package com.foreveross.mofang.serviceconsole.core;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.openkoala.koala.auth.core.domain.User;

/**
 * 渠道实体
 * 
 * @author fb
 */
@Entity
@Table(name="MF_CHANNEL")
public class Channel extends BaseEntity{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	// 渠道名称	
	@NotNull(message = "渠道名称不能为空!")
	@Size(max = 150, message = "名称不能超过150个字符")
	@Column(name = "NAME")
	private String name;
	
	// 渠道全称	字符串	
	@NotNull(message = "渠道全称不能为空!")
	@Size(max = 150, message = "全名称不能超过150个字符")
	@Column(name = "FULLNAME")
	private String  fullName;
	
	//所属组ID	整型	外键，对应同一张表的ID主键
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "GROUP_ID")
	private ChannelGroup group;
	
	//入口访问URL	
	@NotNull(message = "入口url不能为空!")
	@Size(max = 150, message = "入口地址长度不能超过250个字符")
	@Pattern(regexp = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]", message = "url格式错误")
	@Column(name = "ENTRY_URL", length = 500)
	private String entryUrl;
	
	//备注	
	@Size(max = 150, message = "入口地址长度不能超过150个字符")
	@Column(name = "REMARKS", length = 500)
	private String remarks;
	
	@Column(name = "DBTYPE")
	@Enumerated(EnumType.STRING)
	private DBType dbType;
	
	// 是否使用代理IP
	@Column(name = "ISUSEPROXY")
	private Boolean isUseProxy = true;
	
	@Column(name = "TABLENAME")
	private String dbTable;
	
	/**
	 * 创建，会对全称与sn编码进行唯一校验
	 */
	public void save() {
		List<Channel> channel = queryChannel("fullName", this.fullName);
		
		if (!channel.isEmpty()) {
			throw new RuntimeException("己存在相同全称的渠道数据!");
		}
		
		channel = queryChannel("sn", getSn());
		
		if (!channel.isEmpty()) {
			throw new RuntimeException("渠道编号重复!");
		}
		
		super.save();
	}
	
	/**
	 * 更新，会对全称与sn编码进行唯一校验
	 */
	public void update() {
		List<Channel> channel = excludeSelfQueryChannel("fullName", this.fullName);
		
		if (!channel.isEmpty()) {
			throw new RuntimeException("己存在相同全称的渠道数据!");
		}
		
		channel = excludeSelfQueryChannel("sn", getSn());
		
		if (!channel.isEmpty()) {
			throw new RuntimeException("渠道编号重复!");
		}
		
		super.save();
	}
	
	/**
	 * 删除，不会物理删除，修改了状态
	 */
	public void remove(User loginUser) {
		this.setLastUpdate(new Date());
		this.setLastUpdateUser(loginUser);
		this.setRemoved(true);
		super.save();
	}
	
	public void migration(Long group) {
		this.setGroup(ChannelGroup.get(ChannelGroup.class, group));
		super.save();
	}
	
	/**
	 * 删除此组下面的所有渠道【逻辑删除】
	 * 
	 * @param group
	 */
	public static void removes(Group group) {
		getRepository().createJpqlQuery("update Channel c set c.removed = true where  c.removed = false and c.group =:group")
					   .addParameter("group", group)
					   .executeUpdate();
	}
	
	public List<Channel> queryChannel(String field, Object value) {
		return getRepository().createJpqlQuery("select c from Channel c where c.removed=false and c."+ field +"=:"+ field)
					   .addParameter(field, value)
					   .list();
	}
	
	public List<Channel> excludeSelfQueryChannel(String field, Object value) {
		return getRepository().createJpqlQuery("select c from Channel c where c.removed=false and c NOT IN(:channel) and c."+ field +"=:"+ field)
				.addParameter("channel", this)
				.addParameter(field, value)
				.list();
	}
	
	public static enum DBType {
		HBASE("HBase"),
		MYSQL("MySql"),
		ORACLE("Oracle"),
		SQLSERVER("SqlServer"),
		MONGODB("Mongodb");
		
		
		private String lable;
		
		DBType (String lable) {
			this.lable = lable;
		}
		
		public String getLable() {
			return lable;
		}

		public void setLable(String lable) {
			this.lable = lable;
		}
	}


	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getFullName() {
		return fullName;
	}

	public void setFullName(String fullName) {
		this.fullName = fullName;
	}

	public ChannelGroup getGroup() {
		return group;
	}

	public void setGroup(ChannelGroup group) {
		this.group = group;
	}

	public String getEntryUrl() {
		return entryUrl;
	}

	public void setEntryUrl(String entryUrl) {
		this.entryUrl = entryUrl;
	}

	public String getRemarks() {
		return remarks;
	}

	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}

	public DBType getDbType() {
		return dbType;
	}

	public void setDbType(DBType dbType) {
		this.dbType = dbType;
	}

	public Boolean getIsUseProxy() {
		return isUseProxy;
	}

	public void setIsUseProxy(Boolean isUseProxy) {
		this.isUseProxy = isUseProxy;
	}

	public String getDbTable() {
		return dbTable;
	}

	public void setDbTable(String dbTable) {
		this.dbTable = dbTable;
	}
}
